package com.sojoys.chess.game.module;
 
import java.util.Map;
import com.sojoys.artifact.plugin.netty.message.NettyMessage;
import com.xiaoleilu.hutool.date.DateUtil;
import com.xiaoleilu.hutool.log.LogFactory;
import com.sojoys.artifact.exception.LogicModelException;
import com.sojoys.chess.game.module.login.Login;
import java.util.HashMap;
import com.sojoys.artifact.core.IServer;
import com.sojoys.artifact.manager.ByteBuffManager;
import com.xiaoleilu.hutool.log.Log;
import com.sojoys.chess.game.module.desk.Desk;
import com.sojoys.artifact.constant.ArtifactErrorCode;
import com.sojoys.artifact.tools.ToolMap;
import com.sojoys.artifact.factory.session.ISession;
import com.xiaoleilu.hutool.date.TimeInterval;
 
public class Dispatcher {
	static Log log = LogFactory.get(Dispatcher.class);
	private static final Dispatcher INSTANCE = new Dispatcher();
      
    
    public static Dispatcher getInstance() {  
        return INSTANCE;  
    }

	/** 逻辑分发入口 */
	public NettyMessage disp(ISession session,NettyMessage in){
		short commandId = in.getCommandId();
		NettyMessage out = new NettyMessage();
		out.setCommandId(commandId);
		TimeInterval timer = DateUtil.timer();
		try {
			out.setBody(disp(session,commandId, in));
		} catch (LogicModelException e) {
			out.setStatus(e.getCode());
		}catch (Exception e) {
			log.error(e);
			out.setStatus(ArtifactErrorCode.UNKNOWN_ERROR);
		}
		// 记录执行时间
		log.info("commandId : {} execute time : {}",in.getCommandId(), timer.interval());
		
		session.sendMessage(out);
		return out;
	}

	// 逻辑分发
	public byte[] disp(ISession session,short commandId,NettyMessage in) throws LogicModelException {
		byte classCode = (byte) (commandId >> 8);
		switch (classCode) {
			case 2: // 牌桌
				return desk(session, (byte) (commandId ^ classCode << 8),in);
			case 1: // 登陆
				return login(session, (byte) (commandId ^ classCode << 8),in);
			default:
				throw new LogicModelException(ArtifactErrorCode.NOT_FOND_MODULE);
		}
    }
    
    
    /** -----------------------模块开始----------------------- */
    
    
	// 牌桌
	private byte[] desk(ISession session,byte methodCode,NettyMessage in) throws LogicModelException{
		Desk desk = IServer.getModules().getModule(methodCode,Desk.class);
		if(desk == null){
			throw new LogicModelException(ArtifactErrorCode.NOT_FOND_MODULE);
		}
		switch (methodCode) {
		case 1: { // 进入牌桌 [code = 513]
		    com.sojoys.chess.game.protobuf.request.Req_DeskMsg.EnterDesk request = null;
		    try {
		    	request = com.sojoys.chess.game.protobuf.request.Req_DeskMsg.EnterDesk.parseFrom(in.getBody());
		    } catch (Exception e) {
		    	log.error(e);
				throw new LogicModelException(ArtifactErrorCode.PARAM_ERROR);
			}
		    log.info("Parameter : {} ",request);
			return desk.enterDesk(session, request);
		}
		case 2: { // 换桌 [code = 514]
			return desk.switchDesk(session);
		}
		case 3: { // 退出 [code = 515]
		    com.sojoys.chess.game.protobuf.request.Req_DeskMsg.ExitDesk request = null;
		    try {
		    	request = com.sojoys.chess.game.protobuf.request.Req_DeskMsg.ExitDesk.parseFrom(in.getBody());
		    } catch (Exception e) {
		    	log.error(e);
				throw new LogicModelException(ArtifactErrorCode.PARAM_ERROR);
			}
		    log.info("Parameter : {} ",request);
			return desk.exitDesk(session, request);
		}
		default:
			throw new LogicModelException(ArtifactErrorCode.NOT_FOND_MODULE);
		}
	}
	// 登陆
	private byte[] login(ISession session,byte methodCode,NettyMessage in) throws LogicModelException{
		Login login = IServer.getModules().getModule(methodCode,Login.class);
		if(login == null){
			throw new LogicModelException(ArtifactErrorCode.NOT_FOND_MODULE);
		}
		switch (methodCode) {
		case 1: { // 进入游戏 [code = 257]
		    com.sojoys.chess.game.protobuf.request.Req_LoginMsg.EnterGame request = null;
		    try {
		    	request = com.sojoys.chess.game.protobuf.request.Req_LoginMsg.EnterGame.parseFrom(in.getBody());
		    } catch (Exception e) {
		    	log.error(e);
				throw new LogicModelException(ArtifactErrorCode.PARAM_ERROR);
			}
		    log.info("Parameter : {} ",request);
			return login.enterGame(session, request);
		}
		case 2: { // 心跳 [code = 258]
		    com.sojoys.chess.game.protobuf.request.Req_LoginMsg.Heartbeat request = null;
		    try {
		    	request = com.sojoys.chess.game.protobuf.request.Req_LoginMsg.Heartbeat.parseFrom(in.getBody());
		    } catch (Exception e) {
		    	log.error(e);
				throw new LogicModelException(ArtifactErrorCode.PARAM_ERROR);
			}
		    log.info("Parameter : {} ",request);
			return login.heartbeat(session, request);
		}
		default:
			throw new LogicModelException(ArtifactErrorCode.NOT_FOND_MODULE);
		}
	}
}